CLI工具发包过程:调试并优化代码
概述
CLI 工具开发完成后,需要将其发布到 npm 供其他开发者使用。本节介绍发包前的准备工作:包名规范、package.json 配置、bin 字段设置、npm link 本地调试,以及发布流程中的注意事项。
NPM 包名与 create 前缀约定
create 前缀的来源
# 常见的初始化命令
npm init vite@latest # 创建 Vite 项目
npm init vue@latest # 创建 Vue 项目
npm create vue@latest # 等价写法(npm init = npm create)
# 背后的约定:
# npm init/create <initializer>
# 会自动查找 create-<initializer> 包
# 例如 npm init vue → 查找 create-vue 包
bash
包名设计
// package.json
{
"name": "create-vue-template",
"version": "1.0.0",
"description": "CLI for Vue admin template",
"bin": {
"create-vue-template": "./bin/cli.js"
}
}
json
包名与命令名的关系:
├── 包名:create-vue-template
├── bin 命令:create-vue-template
└── 使用方式:npm create vue-template
(等价于 npx create-vue-template)
text
重要:发布前务必在 npm 上搜索包名,确认没有同名包已被占用。
package.json 关键配置
{
"name": "create-vue-template",
"version": "1.0.0",
"description": "CLI for Vue admin template scaffolding",
"type": "module",
"bin": {
"create-vue-template": "./bin/cli.js"
},
"files": [
"bin",
"dist",
"templates"
],
"keywords": [
"vue",
"template",
"cli",
"scaffold",
"admin"
],
"author": "toimc",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/toimc/create-vue-template"
},
"engines": {
"node": ">=16.0.0"
},
"dependencies": {
"commander": "^12.0.0",
"inquirer": "^9.0.0",
"chalk": "^5.0.0",
"ora": "^7.0.0",
"fs-extra": "^11.0.0"
}
}
json
关键字段说明
| 字段 | 作用 | 说明 |
|---|---|---|
name | 包名 | 遵循 create-xxx 约定 |
bin | 可执行命令 | CLI 的入口文件 |
files | 发布文件白名单 | 只发布必要的文件 |
type | 模块类型 | "module" 表示 ESM |
engines | Node 版本要求 | 限制最低 Node 版本 |
bin 入口文件
#!/usr/bin/env node
// bin/cli.js
import { program } from 'commander'
import { createProject } from '../dist/index.js'
program
.name('create-vue-template')
.description('CLI for creating Vue admin template projects')
.version('1.0.0')
.argument('[project-name]', 'Project name')
.option('-t, --template <type>', 'Template type', 'base')
.action(async (projectName, options) => {
await createProject(projectName, options)
})
program.parse()
js
关键点:文件首行的
#!/usr/bin/env node是 shebang 声明,告诉系统使用 Node.js 执行此文件。
本地调试
方式一:npm link
# 在 CLI 项目根目录执行
npm link
# 验证命令是否可用
create-vue-template --version
# 在任意目录测试
mkdir test-project && cd test-project
create-vue-template my-app
# 调试完成后取消链接
npm unlink -g create-vue-template
bash
方式二:直接执行
# 使用 node 直接运行
node ./bin/cli.js my-app
# 或使用 npx
npx . my-app
bash
方式三:使用 npm exec
# 在 package.json 中添加 scripts
{
"scripts": {
"dev": "node ./bin/cli.js",
"test": "node ./bin/cli.js test-project"
}
}
pnpm test
bash
发布流程
1. 准备发布
# 1. 确认代码已构建
pnpm build
# 2. 检查即将发布的文件
npm pack --dry-run
# 3. 确认版本号
npm version patch # 1.0.0 → 1.0.1(修复)
npm version minor # 1.0.0 → 1.1.0(新功能)
npm version major # 1.0.0 → 2.0.0(破坏性变更)
bash
2. 发布到 npm
# 登录 npm(首次)
npm login
# 发布
npm publish
# 发布 scoped 包(如 @toimc/create-vue-template)
npm publish --access public
bash
3. 验证发布结果
# 使用 npx 验证
npx create-vue-template test-app
# 或使用 npm create
npm create vue-template test-app
bash
常见问题与优化
调试时的常见错误
# 错误:command not found
# 原因:bin 字段路径错误或 npm link 未执行
# 解决:检查 package.json 的 bin 路径,重新 npm link
# 错误:Cannot use import statement outside a module
# 原因:缺少 "type": "module" 或文件后缀不对
# 解决:确保 package.json 有 "type": "module",且 import 路径带 .js 后缀
# 错误:Permission denied
# 原因:bin 文件没有执行权限
# 解决:chmod +x bin/cli.js
bash
包名被占用
# 检查包名是否可用
npm search create-vue-template
npm view create-vue-template
# 如果被占用,更换名称
# 如 create-xxx-admin-template
bash
优化建议
CLI 工具优化清单:
├── 代码质量
│ ├── TypeScript 类型检查通过
│ ├── ESLint 无错误
│ └── 代码注释清晰
├── 用户体验
│ ├── 交互式提示(inquirer)
│ ├── 进度反馈(ora spinner)
│ ├── 彩色输出(chalk)
│ └── 错误提示友好
├── 工程化
│ ├── CI/CD 自动发布
│ ├── changelog 自动生成
│ └── 版本号自动管理
└── 文档
├── README.md 使用说明
├── CHANGELOG.md 变更记录
└── 示例项目
text
实践要点
- CLI 包名推荐使用
create-前缀,符合npm init/create的约定,用户可以npm create xxx直接使用 package.json的bin字段定义可执行命令,文件首行必须有#!/usr/bin/env node- 发布前务必检查
files白名单字段,只包含必要的文件,避免发布冗余文件 - 使用
npm link在本地进行调试,确认 CLI 流程跑通后再发布 npm pack --dry-run可以预览即将发布的文件列表,检查是否有遗漏或多余- 包名需要在 npm 上确认可用性,避免与已有包冲突
- 最核心的是把要实现的逻辑想清楚,再寻找合适的工具
↑